﻿using AngleSharp.Dom;
using AngleSharp.Html.Parser;
using HtmlAgilityPack;
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Xml.Serialization;

namespace FieldTools.Util
{
    /// <summary>
    /// XML文档操作帮助类
    /// </summary>
    public class XmlHelper
    {
        /// <summary>
        /// 序列化为XML字符串
        /// </summary>
        /// <param name="obj">对象</param>
        /// <returns></returns>
        public static string Serialize(object obj)
        {
            Type type = obj.GetType();
            MemoryStream Stream = new MemoryStream();
            XmlSerializer xml = new XmlSerializer(type);
            try
            {
                //序列化对象
                xml.Serialize(Stream, obj);
            }
            catch (InvalidOperationException)
            {
                throw;
            }
            Stream.Position = 0;
            StreamReader sr = new StreamReader(Stream);
            string str = sr.ReadToEnd();

            sr.Dispose();
            Stream.Dispose();

            return str;
        }

        /// <summary>
        /// 获取html页面源码
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static HtmlDocument GetHtmlByHtmlWeb(string url)
        {
            HtmlWeb web = new HtmlWeb();
            return web.Load(url);
        }
        /// <summary>
        /// 获取html页面，HttpWebRequest方式，直接返回源码
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static string GetHtmlByHttpWebRequest(string url)
        {
            HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(url);
            HttpWebResponse response = (HttpWebResponse)myReq.GetResponse();
            // Get the stream associated with the response.
            Stream receiveStream = response.GetResponseStream();

            // Pipes the stream to a higher level stream reader with the required encoding format. 
            StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);

            return readStream.ReadToEnd();
        }

        #region HtmlAgilityPack

        /// <summary>
        /// 获取xml单节点数据
        /// </summary>
        /// <param name="htmlDoc"></param>
        /// <param name="xpath"></param>
        /// <returns></returns>
        public static HtmlNode GetHtmlSignalNode(HtmlDocument htmlDoc, string xpath)
        {
            if (htmlDoc == null) return null;
            try
            {
                var node = htmlDoc.DocumentNode.SelectSingleNode(xpath);
                return node;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            return null;
        }
        /// <summary>
        /// 获取xml多节点数据
        /// </summary>
        /// <param name="htmlDoc"></param>
        /// <param name="xpath"></param>
        /// <returns></returns>
        public static HtmlNodeCollection GetHtmlNodes(HtmlDocument htmlDoc, string xpath)
        {
            if (htmlDoc == null) return null;
            try
            {
                var nodes = htmlDoc.DocumentNode.SelectNodes(xpath);
                return nodes;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            return null;
        }
        #endregion

        #region AngleSharp
        /// <summary>
        /// 获取多节点数据，AngleSharp实现
        /// </summary>
        /// <param name="htmlSourceCode"></param>
        /// <param name="selectors">（注意与xpath语法的区别）</param>
        /// <returns></returns>
        public static IHtmlCollection<IElement> GetElementsByAngleSharp(string htmlSourceCode, string selectors)
        {
            if (htmlSourceCode == null) return null;
            try
            {
                var parser = new HtmlParser();
                var document = parser.ParseDocument(htmlSourceCode);
                var collection = document.QuerySelectorAll(selectors);
                return collection;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            return null;
            //Console.WriteLine($"Serializing the (original) document: {document.QuerySelector("h1").OuterHtml}");
            //Console.WriteLine($"Serializing the (original) document: {document.QuerySelector("html > body > h1").OuterHtml}");
        }
        /// <summary>
        /// 获取节点数据(第一个)，AngleSharp实现
        /// </summary>
        /// <param name="htmlSourceCode"></param>
        /// <param name="selectors">（注意与xpath语法的区别）</param>
        /// <returns></returns>
        public static IElement GetElementByAngleSharp(string htmlSourceCode, string selectors)
        {
            if (htmlSourceCode == null) return null;
            try
            {
                var parser = new HtmlParser();
                var document = parser.ParseDocument(htmlSourceCode);
                var elment = document.QuerySelector(selectors);
                return elment;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            return null;
        }
        #endregion
    }
}
